import imp
import os
import sys
from optparse import OptionParser
from nose.config import Config
from nosedjango import NoseDjango

# mock options bucket
class Bucket:
    pass

# helpers
def make_settings(settings, mod_name='nosedjango.settings'):
    """Create a fake module to hold test settings in settings.
    """
    setm = imp.new_module(mod_name)
    for k, v in settings.items():
        setattr(setm, k, v)
    sys.modules[mod_name] = setm
    os.environ['DJANGO_SETTINGS_MODULE'] = mod_name
    return setm

# FIXME move to own file?
# models for use in testing
def make_models():
    from django.db import models

    class Zoo(models.Model):
        name = models.CharField(maxlength=100)
        class Meta:
            app_label = 'nosedjango.tests'
        
    class Animal(models.Model):
        zoo = models.ForeignKey(Zoo)
        species = models.CharField(maxlength=100)
        name = models.CharField(maxlength=100)
        class Meta:
            app_label = 'nosedjango.tests'

    # fake models module
    app = imp.new_module('nosedjango.tests.models')
    app.Zoo = Zoo
    app.Animal = Animal
    app.__file__ = '/not/a/real/module.py'
    return app

# FIXME
# looks like it will be necessary to monkeypatch in a mock db connection
# to do disconnected tests, since the 'dummy' backend is just an error
# trap.

#
# TESTS
#

def test_helpers():
    """make sure our helper functions work
    """
    settings = make_settings({'DATABASE_NAME':':memory:',
                              'DATABASE_ENGINE':'sqlite3',
                              'INSTALLED_APPS':('nosedjango.tests',)})
    app = make_models()
    from django.core import management
    management.install(app)
    
# function/units
def test_config_basic():
    # basic: enable, and inject django settings/manage files into ignoreFiles
    parser = OptionParser()
    conf = Config()
    argv = ['proggy', '--with-django']
    env = {}

    plug = NoseDjango()
    plug.add_options(parser, env)
    options, args = parser.parse_args(argv)
    assert options.enable_plugin_django    
    plug.configure(options, conf)
    assert plug.enabled
    assert plug.ignoreDjangoFiles in conf.ignoreFiles

def test_config_settings():
    # settings module can be set via config

    parser = OptionParser()        
    conf = Config()
    argv = ['proggy', '--with-django', '--django-settings=some.settings']
    env = {}
    
    plug = NoseDjango()
    plug.add_options(parser, env)
    options, args = parser.parse_args(argv)
    assert options.enable_plugin_django
    assert options.django_settings == 'some.settings'
    plug.configure(options, conf)
    assert plug.enabled
    assert plug.ignoreDjangoFiles in conf.ignoreFiles
    assert env['DJANGO_SETTINGS_MODULE'] == 'some.settings'

def test_config_test_db():
    # use particular test db

    parser = OptionParser()        
    conf = Config()
    env = {}    
    argv = ['proggy', '--with-django', '--django-test-db=testdb']
    plug = NoseDjango()
    plug.add_options(parser, env)
    options, args = parser.parse_args(argv)
    plug.configure(options, conf)
    assert plug.test_db == 'testdb'
    assert plug.test_schema is None
    
def test_config_test_schema():
    # use test schema instead of test db
    parser = OptionParser()        
    conf = Config()
    env = {}
    argv = ['proggy', '--with-django', '--django-test-schema=testschema']
    plug = NoseDjango()
    plug.add_options(parser, env)
    options, args = parser.parse_args(argv)
    plug.configure(options, conf)    
    assert plug.test_db is None
    assert plug.test_schema == 'testschema'

def test_config_test_db_schema():
    # use test schema in test db
    parser = OptionParser()        
    conf = Config()
    env = {}
    argv = ['proggy', '--with-django', '--django-test-db=testdb', 
            '--django-test-schema=testschema']
    plug = NoseDjango()
    plug.add_options(parser, env)
    options, args = parser.parse_args(argv)
    plug.configure(options, conf)
    assert plug.test_db == 'testdb'
    assert plug.test_schema == 'testschema'
    
def test_begin():
    # using dummy driver(?), test that begin() creates the test db and
    # disconnects from the real db, and fills the test db with models
    assert False, "No test"

def test_begin_name_clash():
    # using dummy driver(?), test that begin() will error out if the test
    # db already exists
    assert False, "No test"


def test_finalize():
    # test that finalize() clears out the test db in a non-destructive
    # manner (only clear a db we created)
    assert False, "No test"

# full tests
    
def test_sqlite3():
    """setup/teardown with sqlite3 database
    """
    assert False, "No test"

def test_test_db():
    """setup/teardown with test db
    """
    assert False, "No test"

def test_test_schema():
    """setup/teardown with test schema (postgres only)
    """
    assert False, "No test"
